package com.saitron.zhky.provider.health.web;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * 文件相关工具类
 *
 * @author tang
 */
public class FileUtil {

    /**
     * 判断文件大小是否合乎指定大小，如果超出，返回false，否则返回true
     * @param file
     * @param size_MB
     * @return
     */
    public static boolean checkFileSize(File file, int size_MB) {
        long size = size_MB * 1024 * 1024;
        return file.length() > size ? false : true;
    }

    public static String makeNewFileName(String originalFileName) {
        return System.currentTimeMillis() + String.format("%03d", new Random().nextInt(1000)) + originalFileName.substring(originalFileName.indexOf("."));
    }

    /**
     * 修改文件后缀
     * @param filePath
     * @param newPostfix 文件后缀不带'.'
     * @return
     */
    public static String resetPostfix(String filePath, String newPostfix) {
        String targetPath;
        int point_index = filePath.lastIndexOf(".");
        if (point_index != -1) {
            targetPath = filePath.substring(0, point_index) + "." + newPostfix;
        } else {
            targetPath = filePath + "." + newPostfix;
        }
        return targetPath;
    }

    /**
     * 获取文件所在的文件夹路径
     * @param filePath
     * @return
     */
    public static String getFolderPath(String filePath) {
        return new File(filePath).getParent();
    }

    /**
     * 获取文件后缀名，不包括'.'
     * @param filePath
     * @return
     */
    public static String getPostfix(String filePath) {
        String name=new File(filePath).getName();
        int lastIndexOf = name.lastIndexOf(".");
        if (lastIndexOf >= 0) {
            return name.substring(lastIndexOf + 1);
        }
        return "";
    }

    /**
     * 获取文件后缀名，包括'.'
     * @param filePath
     * @return
     */
    public static String getSuffiex(String filePath) {
        String name=new File(filePath).getName();
        int lastIndexOf = name.lastIndexOf(".");
        if (lastIndexOf >= 0) {
            return name.substring(lastIndexOf);
        }
        return "";
    }

    /**
     * 获取文件名，不包括文件后缀名
     * @param filePath
     * @return
     */
    public static String getPureName(String filePath) {
        File file=new File(filePath);
        String name = file.getName();
        int lastIndexOf = name.lastIndexOf(".");
        if (lastIndexOf >= 0) {
            return name.substring(0, lastIndexOf);
        }
        return name;
    }

    public static String getFileName(String filePath) {
        File file=new File(filePath);
        String name = file.getName();
        return name;
    }

    /**
     * 文件是否存在
     * @param file
     * @return
     */
    public static boolean exists(File file) {
        return file != null && file.exists();
    }

    /**
     * 文件是否能写
     * @param targetFile
     * @return
     */
    public static boolean isCanWrite(File targetFile) {
        if (targetFile == null) {
            return false;
        }
        if (targetFile.isDirectory()) {
            return false;
        }
        if (!targetFile.exists()) {
            return true;
        }
        try (FileOutputStream fos = new FileOutputStream(targetFile, true)) {
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static String readTextFile(File file) {
        return readTextFile(file, "UTF-8");
    }

    public static String readTextFile(File file, String code) {
        try {
            return new String(Files.readAllBytes(file.toPath()), code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建一个文件或文件夹，自动创建不存在的上级目录，如果文件或文件夹存在则不创建，
     * @param filePath
     * @return
     */
    public static File createFile(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return file;
        }
        if (file.isDirectory()) {
            file.mkdirs();
            return file;
        }
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        try {
            file.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 保存字符串到一个文本文件（UTF-8），如果文件不存在则创建
     * @param filePath
     * @param content 文件内容
     */
    public static void saveTextFile(String filePath, String content) {
        saveTextFile(new File(filePath), content);
    }

    /**
     * 保存字符串到一个文本文件（UTF-8），如果文件不存在则创建
     * @param file
     * @param content 文件内容
     */
    public static void saveTextFile(File file, String content) {
        saveTextFile(file, content, "UTF-8");
    }

    /**
     * 保存字符串到一个文本文件，如果文件不存在则创建
     * @param file
     * @param content 文件内容
     * @param code 文件内容编码
     */
    public static void saveTextFile(File file, String content, String code) {
        try {
            deleteFile(file);//不删除的话，写入的内容可能会莫名其妙多出一些东西，原因未知
            Files.write(file.toPath(), content.getBytes(code), StandardOpenOption.CREATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除一个文件或文件夹（递归）
     * @param file
     */
    public static void deleteFile(File file) {
        if (!exists(file)) {
            return;
        }
        if (file.isDirectory()) {
            File[] listFiles = file.listFiles();
            for (int i = 0; i < listFiles.length; i++) {
                deleteFile(listFiles[i]);
            }
            // Files.delete(file.toPath());
            file.delete();
        } else {
            file.delete();
        }
    }

    /**
     * 移动一个文件或文件夹（递归）
     */
    public static void moveFile(File sourceFile, File targetFile) {
        if (!exists(sourceFile)) {
            return;
        }
        if (sourceFile.isDirectory()) {
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            File[] listFiles = sourceFile.listFiles();
            for (int i = 0; i < listFiles.length; i++) {
                File childTargetFile = new File(targetFile.getPath() + File.separator + listFiles[i].getName());
                moveFile(listFiles[i], childTargetFile);
            }
            sourceFile.delete();
        } else {
            try {
                if (!targetFile.getParentFile().exists()) {
                    targetFile.getParentFile().mkdirs();
                }
                Files.move(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 复制一个文件或文件夹（递归）
     */
    public static void copyFile(File sourceFile, File targetFile) {
        if (!exists(sourceFile)) {
            return;
        }
        if (sourceFile.isDirectory()) {
            if (!targetFile.exists()) {
                targetFile.mkdirs();
            }
            File[] listFiles = sourceFile.listFiles();
            for (int i = 0; i < listFiles.length; i++) {
                File childTargetFile = new File(targetFile.getPath() + File.separator + listFiles[i].getName());
                copyFile(listFiles[i], childTargetFile);
            }
        } else {
            try {
                if (!targetFile.getParentFile().exists()) {
                    targetFile.getParentFile().mkdirs();
                }
                Files.copy(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 从字节输入流中读取所有字节
     * @param in
     * @return
     * @throws IOException
     */
    public static byte[] readAllBytes(InputStream in) throws IOException {
        return readAllBytes(in, 2048);
    }
    /**
     * 从字节输入流中读取所有字节
     * @param in
     * @param initialSize 初始化字节数组长度，推荐设置为1024的整数倍
     * @return
     * @throws IOException
     */
    public static byte[] readAllBytes(InputStream in, int initialSize) throws IOException {
        try (InputStream _in = in) {
            int capacity = initialSize;
            byte[] buf = new byte[capacity];
            int nread = 0;
            int rem = buf.length;
            for (int n = _in.read(buf, nread, rem); n > 0; n = _in.read(buf, nread, rem)) {
                nread += n;
                rem -= n;
                assert rem >= 0;
                if (rem == 0) {
                    int newCapacity = capacity << 1;
                    if (newCapacity < 0) {
                        if (capacity == Integer.MAX_VALUE)
                            throw new OutOfMemoryError("Required array size too large");
                        newCapacity = Integer.MAX_VALUE;
                    }
                    rem = newCapacity - capacity;
                    buf = Arrays.copyOf(buf, newCapacity);
                    capacity = newCapacity;
                }
            }
            return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * 从字节输入流中读取所有字符串（UTF-8）
     * @param in
     * @return
     * @throws IOException
     */
    public static String readAllString(InputStream in) throws IOException {
        return readAllString(in, Charset.forName("UTF-8"));
    }

    /**
     * 从字节输入流中读取所有字符串（指定编码）
     * @param in
     * @param code
     * @return
     * @throws IOException
     */
    public static String readAllString(InputStream in, Charset code) throws IOException {
        if (code == null) {
            code = Charset.forName("UTF-8");
        }
        try (BufferedInputStream bis = new BufferedInputStream(in);
             InputStreamReader isr = new InputStreamReader(bis, code.newDecoder());
             BufferedReader reader = new BufferedReader(isr)) {
            StringBuffer sb = new StringBuffer();
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                sb.append(line);
            }
            return sb.toString();
        }
    }

    /**
     * 从字符流中读取所有字符串
     * @param r
     * @return
     * @throws IOException
     */
    public static String readAllString(Reader r) throws IOException {
        return readAllString(r, 1024);
    }

    /**
     * 从字符流中读取所有字符串
     * @param r
     * @param initialSize 初始化字符数组长度，推荐设置为1024的整数倍
     * @return
     * @throws IOException
     */
    public static String readAllString(Reader r, int initialSize) throws IOException {
        try (BufferedReader br = new BufferedReader(r)) {
            StringBuffer sb = new StringBuffer();
            char[] b = new char[initialSize];
            for (int i = br.read(b); i > 0; i = br.read(b)) {
                sb.append(new String(b, 0, i));
            }
            return sb.toString();
        }
    }

    /**
     * 从字节输入流中读取所有字符串（UTF-8），并按行返回List
     * @param in
     * @return
     * @throws IOException
     */
    public static List<String> readAllLines(InputStream in) throws IOException {
        return readAllLines(in, "UTF-8");
    }

    /**
     * 从字节输入流中读取所有字符串（指定编码），并按行返回List
     * @param in
     * @param code
     * @return
     * @throws IOException
     */
    public static List<String> readAllLines(InputStream in, String code) throws IOException {
        try (Reader r = code == null ? new InputStreamReader(in) : new InputStreamReader(in, code)) {
            return readAllLines(r);
        }
    }

    /**
     * 从字符输入流中读取所有字符串，并按行返回List
     * @param r
     * @return
     * @throws IOException
     */
    public static List<String> readAllLines(Reader r) throws IOException {
        try (BufferedReader br = new BufferedReader(r)) {
            List<String> result = new ArrayList<>();
            for (String line = br.readLine(); line != null; line = br.readLine()) {
                result.add(line);
            }
            return result;
        }
    }
}
